main.ts ➔ init   A
last analyzed

Complexity

Conditions 2

Size

Total Lines 23
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 20
dl 0
loc 23
rs 9.4
c 0
b 0
f 0
cc 2
1
import { getTranslation } from './modules/i18n';
2
import {
3
  resetBoxes,
4
  loadWordlist,
5
  elements,
6
  determineUILanguage,
7
  getGitHashOrDefault,
8
  validateModalElement,
9
  validateButtonElements,
10
  isEscapeKey,
11
  isModalOpen,
12
  getModalTransitionDuration,
13
} from './modules/bip39';
14
import { initTheme, toggleTheme } from './modules/theme';
15
import { initLanguage, setupLanguageToggle, setTranslations, updateUITranslations } from './modules/language';
16
import { createGrid } from './modules/grid';
17
import { updateDisplay } from './modules/display';
18
import { setupWordInput, clearWordInput } from './modules/wordInput';
19
20
function handleReset(): void {
21
  resetBoxes();
22
  clearWordInput();
23
  updateDisplay();
24
}
25
26
function openLearnModal(modal: HTMLElement): void {
27
  modal.removeAttribute('hidden');
28
  modal.setAttribute('aria-hidden', 'false');
29
  document.body.style.overflow = 'hidden';
30
31
  setTimeout(() => {
32
    const firstFocusable = modal.querySelector<HTMLElement>(
33
      'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
34
    );
35
    firstFocusable?.focus();
36
  }, 100);
37
}
38
39
function closeLearnModal(modal: HTMLElement): void {
40
  modal.setAttribute('aria-hidden', 'true');
41
  setTimeout(() => {
42
    modal.setAttribute('hidden', '');
43
    document.body.style.overflow = '';
44
  }, getModalTransitionDuration());
45
}
46
47
function setupModalEventListeners(
48
  learnBtn: HTMLElement,
49
  modal: HTMLElement,
50
  modalClose: HTMLElement,
51
  modalOverlay: Element | null
52
): void {
53
  learnBtn.addEventListener('click', () => openLearnModal(modal));
54
  modalClose.addEventListener('click', () => closeLearnModal(modal));
55
  modalOverlay?.addEventListener('click', () => closeLearnModal(modal));
56
}
57
58
function setupModalKeyboardHandler(modal: HTMLElement): void {
59
  document.addEventListener('keydown', e => {
60
    if (isEscapeKey(e.key) && isModalOpen(modal.getAttribute('aria-hidden'))) {
61
      e.preventDefault();
62
      closeLearnModal(modal);
63
    }
64
  });
65
}
66
67
function setupLearnModal(): void {
68
  const learnBtn = document.getElementById('learn-more-btn');
69
  const modal = document.getElementById('learn-modal');
70
  const modalClose = document.getElementById('modal-close');
71
  const modalOverlay = modal?.querySelector('.modal-overlay') ?? null;
72
73
  if (!validateButtonElements(learnBtn, modalClose) || !validateModalElement(modal)) return;
74
75
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
76
  setupModalEventListeners(learnBtn!, modal!, modalClose!, modalOverlay);
77
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
78
  setupModalKeyboardHandler(modal!);
79
}
80
81
async function init(): Promise<void> {
82
  initTheme();
83
  const savedLanguage = initLanguage();
84
85
  const uiLang = determineUILanguage(savedLanguage);
86
  setTranslations(getTranslation(uiLang));
87
88
  updateUITranslations();
89
  await loadWordlist(savedLanguage);
90
  createGrid();
91
  setupWordInput();
92
93
  // Inject git commit hash into footer
94
  const gitHashElement = document.getElementById('git-hash');
95
  if (gitHashElement) {
96
    gitHashElement.textContent = getGitHashOrDefault(import.meta.env.VITE_GIT_HASH);
97
  }
98
99
  elements.resetButton.addEventListener('click', handleReset);
100
  elements.themeToggle.addEventListener('click', toggleTheme);
101
  setupLanguageToggle();
102
  setupLearnModal();
103
}
104
105
init().catch(error => {
106
  console.error('Failed to initialize application:', error);
107
});
108